import {
  UploadFile,
  UploadFiles,
  UploadProgressEvent,
  UploadRawFile,
  UploadRequestOptions,
  UploadUserFile,
} from 'element-plus/es/components/upload';
import { Awaitable } from 'element-plus/es/utils';
import { CSSProperties } from 'vue';
import { RuleItem } from './rule';

export type ComponentType =
  | 'cascader'
  | 'checkbox'
  | 'checkbox-group'
  | 'checkbox-button'
  | 'color-picker'
  | 'date-picker'
  | 'input'
  | 'input-number'
  | 'radio'
  | 'radio-group'
  | 'radio-button'
  | 'rate'
  | 'select'
  | 'option'
  | 'slider'
  | 'switch'
  | 'time-picker'
  | 'time-select'
  | 'transfer'
  | 'upload'
  | 'editor';

export interface FormOptions {
  // 表单项显示的元素
  type: ComponentType;
  value?: SafeAny;
  label?: string;
  // 表单标识
  prop: string;
  // 表单项的验证规则
  rules?: RuleItem[];
  // 表单项的特有属性
  attrs?: {
    clearable?: boolean;
    showPassword?: boolean;
    disabled?: boolean;
    style?: CSSProperties;
    [key: string]: SafeAny;
  };
  // 表单项的占位符
  placeholder?: string;
  children?: Omit<FormOptions, 'prop'>[];
  uploadAttrs?: {
    action: string;
    headers?: Headers | Record<string, any>;
    method?: 'post' | 'put' | 'patch';
    multiple?: boolean;
    data?: Record<string, any>;
    name?: string;
    withCredentials?: boolean;
    showFileList?: boolean;
    drag?: boolean;
    accept?: string;
    thumbnailMode?: boolean;
    fileList?: UploadUserFile[];
    listType?: 'text' | 'picture' | 'picture-card';
    autoUpload?: boolean;
    disabled?: boolean;
    limit?: number;
  };
  uploadHooks?: {
    onPreview?: (uploadFile: UploadFile) => void;
    onRemove?: (uploadFile: UploadFile, uploadFiles: UploadFiles) => void;
    onSuccess?: (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => void;
    onError?: (error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles) => void;
    onProgress?: (evt: UploadProgressEvent, uploadFile: UploadFile, uploadFiles: UploadFiles) => void;
    onChange?: (uploadFile: UploadFile, uploadFiles: UploadFiles) => void;
    onExceed?: (files: File[], uploadFiles: UploadUserFile[]) => void;
    beforeUpload?: (rawFile: UploadRawFile) => Awaitable<void | undefined | null | boolean | File | Blob>;
    beforeRemove?: (uploadFile: UploadFile, uploadFiles: UploadFiles) => Awaitable<boolean>;
    httpRequest?: (options: UploadRequestOptions) => XMLHttpRequest;
  };
}
